/*
 * @Author: 小花
 * @Date: 2022-04-07 08:59:22
 * @LastEditors: 小花
 * @LastEditTime: 2022-05-16 21:46:17
 * @FilePath: /vue3-teap/src/plugins/request/axios.ts
 * @Description:
 */
import axios, { AxiosRequestConfig, AxiosRequestHeaders, AxiosResponse, Canceler } from 'axios'
import router from '@/plugins/router/router'

import { responseEnum, responseUtil } from './responseUtil'
import { useStore } from '@/plugins/store/store'
import { ElMessage } from 'element-plus'

axios.defaults.baseURL = 'http://localhost:8081'
axios.defaults.timeout = 15000
axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8'

const CancelToken = axios.CancelToken
type config = {
  url: string,
  cancel: Canceler
}
const pending = new Array<config>()
const repeatRequestHandler = (config: AxiosRequestConfig) => {
  const flag = `${config.method}&${config.url}`
  pending.some((value, index) => {
    if (value.url !== flag) return false
    value.cancel('405')
    pending.splice(index, 1)
    return true
  })
}

axios.interceptors.request.use((config: AxiosRequestConfig) => {
  const store = useStore()
  const headers = config.headers as AxiosRequestHeaders
  headers.satoken = store.userData.satoken ? store.userData.satoken : ''
  repeatRequestHandler(config)
  config.cancelToken = new CancelToken(canceler => {
    pending.push({ url: `${config.method}&${config.url}`, cancel: canceler })
  })

  return config
}, error => {
  return Promise.reject(error)
})

let noPermissionDebounceTimer: NodeJS.Timeout | undefined

axios.interceptors.response.use((response: AxiosResponse<responseUtil>) => {
  repeatRequestHandler(response.config)
  const store = useStore()
  // 登录失效
  if (response.data.code === responseEnum.LOGIN_FAILURE) {
    ElMessage.closeAll()
    ElMessage.warning(response.data.msg)
    store.userData = <any>{}
    router.replace({ path: '/' })
  }

  // 暂无权限
  if (response.data.code === responseEnum.NO_PERMISSION) {
    noPermissionDebounceTimer && clearTimeout(noPermissionDebounceTimer)
    noPermissionDebounceTimer = setTimeout(() => {
      ElMessage.warning(response.data.msg)
    }, 10)
  }
  return response
}, (error) => {
  import('@/plugins/request/status').then(module => {
    ElMessage.error(module.showMessage(error.status || error.message))
  })
  return Promise.reject(error)
})

export default axios
